using System.Collections;
using System.Collections.Generic;


[System.Xml.Serialization.XmlRootAttribute("lists", Namespace = "")]
public class GitInfoLists
{
	public class entry
	{
		public class Commit
		{
			[System.Xml.Serialization.XmlAttribute()]
			public int revision;
		}

		public string name;
		public Commit commit;
		[System.Xml.Serialization.XmlAttribute()]
		public string kind;

		public bool isFile()
		{
			return kind == "file";
		}
	}

	public class EntryList: List<entry>
	{
//		[System.Xml.Serialization.XmlAttribute()]
//		public string path;
	}

	public EntryList list;

}

public static class GitTool
{
    static string GetGitPath()
    {
        if(System.IO.File.Exists("/usr/local/bin/git"))
        {
            return "/usr/local/bin/git";
        }
        else
        {
            return "git";
        }
    }

// 	public static Dictionary<string, int> GetSvnInfo(HashSet<string> paths, out string err, string otherParams = null)
// 	{
// 		HashSet<string> dirs = new HashSet<string>();
// 		foreach (var path in paths)
// 		{
//             if (System.IO.Directory.Exists(path))
//             {
//                 dirs.Add(path);
//             }
//             else
//             {
//                 dirs.Add(System.IO.Path.GetDirectoryName(path));
//             }
// 		}

// 		HashSet<string> tempSet = new HashSet<string>(dirs);

// 		foreach (var s in tempSet)
// 		{
// 			string dir = s;
// 			do
// 			{
// 				dir = System.IO.Path.GetDirectoryName(dir);
// 				if(dirs.Contains(dir))
// 				{
// 					dirs.Remove(s);
// 					break;
// 				}
// 			}
// 			while(!string.IsNullOrEmpty(dir));
// 		}

// 		Dictionary<string, int> result = new Dictionary<string, int>();
// 		err = null;

// //		string log = dirs.Count + "\n";
// //		foreach (var d in dirs)
// //		{
// //			log += d + "\n";
// //		}
// //		UnityEngine.Debug.LogError(log);

// 		foreach (var path in dirs)
// 		{
// 			Dictionary<string, int> temp = GetSvnInfo(path, out err, otherParams);
// 			if (!string.IsNullOrEmpty(err))
// 			{
// 				err = "GetSvnInfo failed: " + path + "\n" + err;
// 				return null;
// 			}

// 			if (temp != null)
// 			{
// 				foreach (var entry in temp)
// 				{
// 					result.Add(entry.Key, entry.Value);
// 				}
// 			}
// 		}

// 		return result;
// 	}

// 	public static Dictionary<string, int> GetSvnInfo(string path, out string err, string otherParams = null)
// 	{
// 		if (!System.IO.Directory.Exists(path))
// 		{
// 			err = null;
// 			return null;
// 		}

// 		string output = null;
//         err = null;
// //		err = CommandLineTool.cmdWithOutput("pwd", "", ref output);
// //		UnityEngine.Debug.LogError("pwd: " + output);

// 		int exitCode = CommandLineTool.CmdWithOutput(GetSvnPath(), "ls --xml -R \"" + path + "\" " + otherParams, ref output, ref err);
//         if (exitCode != 0)
// 		{
// 			return null;
// 		}
// 		string str = output;

// 		System.IO.StringReader strReader = new System.IO.StringReader(str);
// 		System.Xml.Serialization.XmlSerializer xmldes = new System.Xml.Serialization.XmlSerializer(typeof(SvnInfoLists));
// 		SvnInfoLists info = xmldes.Deserialize(strReader) as SvnInfoLists;

// 		Dictionary<string, int> result = new Dictionary<string, int>();
// 		foreach (var t in info.list)
// 		{
// 			result.Add(path + "/" + t.name, t.commit.revision);
// 		}
// 		return result;
// 	}

//     public static HashSet<string> GetModifiedFileSet(int comparedSvnVersion, string otherParams = null)
//     {
//         HashSet<string> modifiedPathSet = new HashSet<string>();
//         string output = null;
//         string err = null;
//         int exitCode = CommandLineTool.CmdWithOutput(GetSvnPath(), "info --show-item last-changed-revision", ref output, ref err);
//         if (exitCode != 0)
//         {
//             throw new System.Exception(err);
//         }
//         int lastChangedVersion = int.Parse(output);



//         string output2 = null;
//         string err2 = null;
//         int exitCode2 = CommandLineTool.CmdWithOutput(GetSvnPath(), "info --show-item relative-url", ref output2, ref err2);
//         if (exitCode2 != 0)
//         {
//             throw new System.Exception(err2);
//         }
//         output2 = output2.Replace("\n", "");

//         if (output2.EndsWith("\r"))
//         {
//             output2 = output2.Substring(0, output2.Length - 1);
//         }
//         string needRemovePath = output2.Substring(1, output2.Length - 1) + "/";




//         int oldConfigVersion = comparedSvnVersion;

//         //            Debug.LogError("test svn2: " + lastChangedVersion + "  " + oldConfigVersion);
//         if (oldConfigVersion != lastChangedVersion)
//         {
//             if (lastChangedVersion > oldConfigVersion)
//             {
//                 oldConfigVersion++;
//             }
//             else
//             {
//                 oldConfigVersion--;
//             }

//             exitCode = CommandLineTool.CmdWithOutput(GetSvnPath(), "log -r " + lastChangedVersion + ":" + oldConfigVersion + " . -v " + otherParams, ref output, ref err);



//             if (exitCode != 0)
//             {
//                 throw new System.Exception(err);
//             }

//             //                Debug.LogError("test svn: " + output);

//             System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"^[ ]+.[ ]+(.*)");


//             System.IO.StringReader strReader = new System.IO.StringReader(output);
//             while (true)
//             {
//                 string line = strReader.ReadLine();
//                 if (line == null)
//                 {
//                     break;
//                 }

//                 System.Text.RegularExpressions.Match match = regex.Match(line);
//                 if (match.Success)
//                 {
//                     string assetPath = match.Groups[1].Value;
//                     if (assetPath + "/" == needRemovePath)
//                     {
//                         continue;
//                     }

//                     if (assetPath.Length - needRemovePath.Length < 0)
//                     {
//                         UnityEngine.Debug.LogException(new System.Exception("length error:  " + assetPath + "  " + assetPath.Length + "  " + needRemovePath + "  " + needRemovePath.Length));
//                     }

//                     assetPath = assetPath.Substring(needRemovePath.Length, assetPath.Length - needRemovePath.Length);
// //                    if (assetPath.EndsWith(".meta"))
// //                    {
// //                        assetPath = assetPath.Substring(0, assetPath.Length - 5);
// //                    }

//                     modifiedPathSet.Add(assetPath);
//                 }
//             }
//         }

//         return modifiedPathSet;
//     }

//     public static HashSet<string> GetCurrentModifiedFileSet()
//     {
//         HashSet<string> modifiedPathSet = new HashSet<string>();

//         string output = null;
//         string err = null;
//         int exitCode = CommandLineTool.CmdWithOutput(GetSvnPath(), "st", ref output, ref err);



//         if (!string.IsNullOrEmpty(err))
//         {
//             throw new System.Exception(err);
//         }

//         //                Debug.LogError("test svn: " + output);

//         System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"^[ ]*[^ ]+[ ]*(.*)");


//         System.IO.StringReader strReader = new System.IO.StringReader(output);
//         while (true)
//         {
//             string line = strReader.ReadLine();
//             if (line == null)
//             {
//                 break;
//             }

//             System.Text.RegularExpressions.Match match = regex.Match(line);
//             if (match.Success)
//             {
//                 string assetPath = match.Groups[1].Value;

//                 modifiedPathSet.Add(assetPath);
//             }
//         }

//         return modifiedPathSet;
//     }

    public static string GetLastChangedVersion(string path)
    {
        string output = null;
        string err = null;
        string dir = System.IO.Path.GetDirectoryName(path);
        int exitCode = CommandLineTool.CmdExWithOutput(GetGitPath(), "log -1 --format=%H " + path, dir, false, true, ref output, true, ref err);
        if (exitCode != 0)
        {
            return null;
        }

        return output;
    }

    public static string MergeToVersion(string path, string version, string otherParams = null)
    {
        string output = null;
        string err = null;
        string dir = System.IO.Path.GetDirectoryName(path);
        string param = "reset " + version;
        int exitCode = CommandLineTool.CmdExWithOutput(GetGitPath(), param, dir, false, true, ref output, true, ref err);
        return exitCode == 0? null: err;
    }
}